﻿using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Configuration;
using System.Runtime.CompilerServices;
using System.Security.Permissions;
using System.Threading;
using LightCAD.MathLib;

namespace LightCAD.MathLib
{
    public sealed class ThreadContext
    {
        public readonly int id;
        internal static readonly ConcurrentDictionary<int, ThreadContext> Contexts = new ConcurrentDictionary<int, ThreadContext>();
        public readonly FrustumContext FrustumCtx = new FrustumContext();
        public readonly Box2Context Box2Ctx = new Box2Context();
        public readonly Box3Context Box3Ctx = new Box3Context();
        public readonly PlaneContext PlaneCtx = new PlaneContext();
        public readonly RayContext RayCtx = new RayContext();
        public readonly Vector3Context Vector3Ctx = new Vector3Context();
        public readonly EulerContext EulerCtx = new EulerContext();
        public readonly Line3Context Line3Ctx = new Line3Context();
        public readonly Matrix3Context Matrix3Ctx = new Matrix3Context();
        public readonly Matrix4Context Matrix4Ctx = new Matrix4Context();
        public readonly SphereContext SphereCtx = new SphereContext();
        public readonly TriangleContext TriangleCtx = new TriangleContext();
        public readonly Vector3 Vector3 = new Vector3();
        public readonly Vector2 Vector2 = new Vector2();

        private ThreadContext()
        {
            this.id = Thread.CurrentThread.ManagedThreadId;
        }
        [MethodImpl((MethodImplOptions)768)]
        public static ThreadContext GetCurrThreadContext()
        {
            var tctx = ThreadContext.Contexts.GetOrAdd(Thread.CurrentThread.ManagedThreadId, (id) => new ThreadContext());
            return tctx;
        }
        public static int NewId(ConcurrentDictionary<int, int> objIndex)
        {
            var threadId = Thread.CurrentThread.ManagedThreadId;
            return objIndex.AddOrUpdate(threadId, Add, Update);
        }
        private static int Add(int threadId)
        {
            return threadId * (int)(1e+7);
        }
        private static int Update(int threadId, int currId)
        {
            return currId + 1;
        }
    }
}
